/**
 * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.opsli.modulars.customer.customerrelation.web;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.opsli.api.base.result.ResultWrapper;
import org.opsli.api.web.customer.customerinfo.CustomersInfoRestApi;
import org.opsli.api.web.customer.customerrelation.CustomerStudentRelationRestApi;
import org.opsli.api.web.customer.student.CustomersStudentRestApi;
import org.opsli.api.web.tenant.channel.TenantChannelRestApi;
import org.opsli.api.wrapper.customer.customerinfo.CustomersInfoModel;
import org.opsli.api.wrapper.customer.customerrelation.CustomerStudentRelationModel;
import org.opsli.api.wrapper.customer.customerrelation.CustomerStudentRelationQueryModel;
import org.opsli.api.wrapper.customer.student.CustomersStudentModel;
import org.opsli.common.annotation.ApiRestController;
import org.opsli.common.utils.WrapperUtil;
import org.opsli.core.base.controller.BaseRestController;
import org.opsli.core.log.annotation.OperateLogger;
import org.opsli.core.log.enums.ModuleEnum;
import org.opsli.core.log.enums.OperationTypeEnum;
import org.opsli.core.persistence.Page;
import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.WebQueryBuilder;
import org.opsli.modulars.customer.customerrelation.entity.CustomerStudentRelation;
import org.opsli.modulars.customer.customerrelation.service.ICustomerStudentRelationService;
import org.opsli.modulars.customer.student.entity.CustomersStudent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 客户关系 Controller
 *
 * @author guagua
 * @date 2025-06-29 00:14:23
 */
@Api(tags = CustomerStudentRelationRestApi.TITLE)
@Slf4j
@ApiRestController("/{ver}/customer/customerrelation")
public class CustomerStudentRelationRestController extends
        BaseRestController<CustomerStudentRelation, CustomerStudentRelationModel, ICustomerStudentRelationService>
        implements CustomerStudentRelationRestApi {

    @Resource
    TenantChannelRestApi tenantChannelRestApi;
    @Resource
    CustomersInfoRestApi customersInfoRestApi;
    @Resource
    CustomersStudentRestApi customersStudentRestApi;
    @Autowired
    private org.opsli.modulars.customer.record.service.CustomerRecordBusinessService customerRecordBusinessService;

    /**
     * 客户关系 查一条
     *
     * @param model 模型
     * @return ResultWrapper
     */
    @ApiOperation(value = "获得单条客户关系", notes = "获得单条客户关系 - ID")
    @PreAuthorize("hasAuthority('customer_customerrelation_select')")
    @Override
    public ResultWrapper<CustomerStudentRelationModel> get(CustomerStudentRelationModel model) {
        // 如果系统内部调用 则直接查数据库
        if (model != null && model.getIzApi() != null && model.getIzApi()) {
            model = IService.get(model);
        }
        return ResultWrapper.getSuccessResultWrapper(model);
    }

    /**
     * 客户关系 查询分页
     *
     * @param pageNo   当前页
     * @param pageSize 每页条数
     * @param request  request
     * @return ResultWrapper
     */
    @ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器")
    @PreAuthorize("hasAuthority('customer_customerrelation_select')")
    @Override
    public ResultWrapper<?> findPage(Integer pageNo, Integer pageSize, HttpServletRequest request) {

        QueryBuilder<CustomerStudentRelation> queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(),
                request.getParameterMap());
        Page<CustomerStudentRelation, CustomerStudentRelationModel> page = new Page<>(pageNo, pageSize);
        page.setQueryWrapper(queryBuilder.build());
        page = IService.findPage(page);
        return ResultWrapper.getSuccessResultWrapper(page.getPageData());
    }

    /**
     * 客户关系 新增
     *
     * @param model 模型
     * @return ResultWrapper
     */
    @ApiOperation(value = "新增客户关系数据", notes = "新增客户关系数据")
    @PreAuthorize("hasAuthority('customer_customerrelation_insert')")
    @OperateLogger(description = "新增客户关系数据", module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.INSERT, db = true)
    @Override
    @Transactional
    public ResultWrapper<?> insert(CustomerStudentRelationModel model) {
        // 调用新增方法

        // 验证手机号是否存在
        if (customersInfoRestApi.checkPhone(model.getCustomer().getPhone()).getData()) {
            return ResultWrapper.getErrorResultWrapper().setMsg("手机号已存在");
        }
        // 验证渠道是否存在
        if (!tenantChannelRestApi.checkChannel(model.getSourceChannel()).getData()) {
            return ResultWrapper.getErrorResultWrapper().setMsg("渠道不存在");
        }

        // 验证手机号下的学生是否重名
        for (CustomersStudentModel student : model.getStudents()) {
            if (checkStudentName(model.getCustomer().getPhone(), student.getName())) {
                return ResultWrapper.getErrorResultWrapper().setMsg("该手机号已经存在" + student.getName() + ",请重新输入");
            }
        }

        // 添加客户
        CustomersInfoModel customersInfoModel = customersInfoRestApi.insert(model.getCustomer()).getData();
        // 验证客户配置里是否的教学主体是否是学 是 就至少有个学生、否 就不能有学生
        // 判断所有学生的关系字段是否有值
        for (CustomersStudentModel student : model.getStudents()) {
            if (student.getRelationType() == null) {
                return ResultWrapper.getErrorResultWrapper().setMsg("学生关系不能为空");
            }
        }
        // 添加学生
        // 添加客户关系

        for (CustomersStudentModel student : model.getStudents()) {
            String RelationType = student.getRelationType();
            Integer isPrimary = student.getIsPrimary();
            student = customersStudentRestApi.insert(student).getData();
            model.setCustomerId(customersInfoModel.getId());
            model.setStudentId(student.getId());
            model.setRelationType(RelationType);
            model.setIsPrimary(String.valueOf(isPrimary));
            model = IService.insert(model);
            // 创建客户新增记录
            try {
                customerRecordBusinessService.createCustomerAddRecord(model.getId());
            } catch (Exception e) {
                log.warn("创建客户新增记录失败", e);
                // 不影响主业务流程，只记录警告日志
            }
        }

        return ResultWrapper.getSuccessResultWrapperByMsg("新增客户成功");
    }

    /**
     * 验证手机号下的学生是否重名
     *
     * @param phone 手机号
     * @param name  学生姓名
     * @return ResultWrapper
     */
    private Boolean checkStudentName(String phone, String name) {
        CustomersInfoModel customersInfoModel = customersInfoRestApi.getByPhone(phone).getData();
        if (customersInfoModel == null) {
            return false;
        }
        // 先查出该手机号的所有客户关系
        QueryWrapper<CustomerStudentRelation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("customer_id", customersInfoModel.getId());
        List<CustomerStudentRelation> customersStudentRelations = IService.list(queryWrapper);
        // 再查出该手机号的所有学生
        if (customersStudentRelations.isEmpty()) {
            return false;
        }

        QueryWrapper<CustomersStudent> queryWrappers = new QueryWrapper<>();
        queryWrappers.in("id", customersStudentRelations.stream().map(CustomerStudentRelation::getStudentId)
                .collect(Collectors.toList()));
        List<CustomersStudentModel> customersStudents = customersStudentRestApi.Q(queryWrappers).getData();
        // 判断有没有哪个学生名字与name是一样的，只要有一个就返回true
        return customersStudents.stream().anyMatch(student -> student.getName().equals(name));
    }

    /**
     * 客户关系 修改
     *
     * @param model 模型
     * @return ResultWrapper
     */
    @ApiOperation(value = "修改客户关系数据", notes = "修改客户关系数据")
    @PreAuthorize("hasAuthority('customer_customerrelation_update')")
    @OperateLogger(description = "修改客户关系数据", module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.UPDATE, db = true)
    @Override
    public ResultWrapper<?> update(CustomerStudentRelationModel model) {
        // 获取修改前的数据用于记录
        CustomerStudentRelationModel oldCustomerData = null;
        try {
            if (model.getCustomer() != null && model.getCustomer().getId() != null) {
                oldCustomerData = WrapperUtil.transformInstance(IService.getById(model.getId()),
                        CustomerStudentRelationModel.class);
            }
        } catch (Exception e) {
            log.warn("获取旧客户数据失败", e);
        }

        // 验证手机号是否存在
        if (!customersInfoRestApi.checkPhone(model.getCustomer().getPhone()).getData()) {
            return ResultWrapper.getErrorResultWrapper().setMsg("手机号不存在,请先添加");
        }
        // 验证渠道是否存在
        if (!tenantChannelRestApi.checkChannel(model.getSourceChannel()).getData()) {
            return ResultWrapper.getErrorResultWrapper().setMsg("渠道不存在");
        }

        // 验证手机号下的学生是否重名
        for (CustomersStudentModel student : model.getStudents()) {
            if (checkStudentName(model.getCustomer().getPhone(), student.getName())) {
                return ResultWrapper.getErrorResultWrapper().setMsg("该家长下已经存在" + student.getName());
            }
        }

        // 添加客户
        CustomersInfoModel customersInfoModel = customersInfoRestApi.update(model.getCustomer()).getData();
        // 验证客户配置里是否的教学主体是否是学 是 就至少有个学生、否 就不能有学生
        // 判断所有学生的关系字段是否有值
        for (CustomersStudentModel student : model.getStudents()) {
            if (student.getRelationType() == null) {
                return ResultWrapper.getErrorResultWrapper().setMsg("学生关系不能为空");
            }
        }
        // 添加学生
        // 添加客户关系

        for (CustomersStudentModel student : model.getStudents()) {
            String RelationType = student.getRelationType();
            Integer isPrimary = student.getIsPrimary();
            student = customersStudentRestApi.update(student).getData();
            model.setCustomerId(customersInfoModel.getId());
            model.setStudentId(student.getId());
            model.setRelationType(RelationType);
            model.setIsPrimary(String.valueOf(isPrimary));
            IService.update(model);
        }

        // 创建客户修改记录
        try {
            if (oldCustomerData != null && customersInfoModel != null) {
                customerRecordBusinessService.createCustomerUpdateRecord(
                        customersInfoModel.getId(), oldCustomerData, customersInfoModel);
            }
        } catch (Exception e) {
            log.warn("创建客户修改记录失败", e);
            // 不影响主业务流程，只记录警告日志
        }

        return ResultWrapper.getSuccessResultWrapperByMsg("修改客户关系成功");
    }

    /**
     * 客户关系 删除
     *
     * @param id ID
     * @return ResultVo
     */
    @ApiOperation(value = "删除客户关系数据", notes = "删除客户关系数据")
    @PreAuthorize("hasAuthority('customer_customerrelation_delete')")
    @OperateLogger(description = "删除客户关系数据", module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.DELETE, db = true)
    @Override
    public ResultWrapper<?> del(String id) {
        CustomerStudentRelationModel c = IService.get(id);
        IService.delete(id);
        customersInfoRestApi.del(c.getCustomerId());
        customersStudentRestApi.del(c.getStudentId());
        return ResultWrapper.getSuccessResultWrapperByMsg("删除客户关系成功");
    }

    /**
     * 客户关系 批量删除
     *
     * @param ids ID 数组
     * @return ResultVo
     */
    @ApiOperation(value = "批量删除客户关系数据", notes = "批量删除客户关系数据")
    @PreAuthorize("hasAuthority('customer_customerrelation_delete')")
    @OperateLogger(description = "批量删除客户关系数据", module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.DELETE, db = true)
    @Override
    public ResultWrapper<?> delAll(String ids) {
        String[] idArray = Convert.toStrArray(ids);
        IService.deleteAll(idArray);
        return ResultWrapper.getSuccessResultWrapperByMsg("批量删除客户关系成功");
    }

    /**
     * 客户关系 Excel 导出认证
     *
     * @param type    类型
     * @param request request
     */
    @ApiOperation(value = "Excel 导出认证", notes = "Excel 导出认证")
    @PreAuthorize("hasAnyAuthority('customer_customerrelation_export', 'customer_customerrelation_import')")
    @Override
    public ResultWrapper<String> exportExcelAuth(String type, HttpServletRequest request) {
        Optional<String> certificateOptional = super.excelExportAuth(type, CustomerStudentRelationRestApi.SUB_TITLE,
                request);
        if (!certificateOptional.isPresent()) {
            return ResultWrapper.getErrorResultWrapper();
        }
        return ResultWrapper.getSuccessResultWrapper(certificateOptional.get());
    }

    /**
     * 客户关系 Excel 导出
     *
     * @param response response
     */
    @ApiOperation(value = "导出Excel", notes = "导出Excel")
    @PreAuthorize("hasAuthority('customer_customerrelation_export')")
    @OperateLogger(description = "客户关系 导出Excel", module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.SELECT, db = true)
    @Override
    public void exportExcel(String certificate, HttpServletResponse response) {
        // 导出Excel
        super.excelExport(certificate, response);
    }

    /**
     * 客户关系 Excel 导入
     * 注：这里 RequiresPermissions 引入的是 Shiro原生鉴权注解
     *
     * @param request 文件流 request
     * @return ResultVo
     */
    @ApiOperation(value = "导入Excel", notes = "导入Excel")
    @PreAuthorize("hasAuthority('customer_customerrelation_import')")
    @OperateLogger(description = "客户关系 Excel 导入", module = ModuleEnum.MODULE_UNKNOWN, operationType = OperationTypeEnum.INSERT, db = true)
    @Override
    public ResultWrapper<?> importExcel(MultipartHttpServletRequest request) {
        return super.importExcel(request);
    }

    /**
     * 客户关系详细信息 查询分页（包含客户和学生信息）
     *
     * @param pageNo   当前页
     * @param pageSize 每页条数
     * @param request  请求对象，支持动态查询条件
     * @return ResultWrapper
     */
    @ApiOperation(value = "获得客户关系详细信息分页数据", notes = "获得客户关系详细信息分页数据 - 支持动态查询条件")
    @PreAuthorize("hasAuthority('customer_customerrelation_select')")
    @Override
    public ResultWrapper<?> findPageWithDetails(
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
            HttpServletRequest request) {

        // 使用框架的查询构建器，支持动态查询条件如: customerName_LIKE, studentGrade_EQ 等
        QueryBuilder<CustomerStudentRelation> queryBuilder = new WebQueryBuilder<>(IService.getEntityClass(),
                request.getParameterMap());
        Page<CustomerStudentRelation, CustomerStudentRelationModel> page = new Page<>(pageNo, pageSize);
        page.setQueryWrapper(queryBuilder.build());
        page = IService.findPage(page);

        return ResultWrapper.getSuccessResultWrapper(page.getPageData());
    }

    /**
     * 客户关系详细信息 查询分页（支持嵌套查询参数）
     *
     * @param pageNo   当前页
     * @param pageSize 每页条数
     * @return ResultWrapper
     */
    @ApiOperation(value = "获得客户关系详细信息分页数据V2", notes = "获得客户关系详细信息分页数据 - 支持嵌套查询参数")
    @PreAuthorize("hasAuthority('customer_customerrelation_select')")
    @Override
    public ResultWrapper<?> findPageWithDetailsV2(
            @RequestBody CustomerStudentRelationQueryModel queryModel,
            HttpServletRequest request) {

        try {
            // 使用新的查询方法
            Page<CustomerStudentRelation, CustomerStudentRelationModel> page = IService.findPageWithDetails(null,
                    queryModel.getPageNo(), queryModel.getPageSize(), request);
            log.info(request.getParameter("pageSize"));
            return ResultWrapper.getSuccessResultWrapper(page.getPageData());
        } catch (Exception e) {
            log.error("查询客户关系详细信息分页数据失败", e);
            return ResultWrapper.getErrorResultWrapper().setMsg("查询失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID查询客户关系详细信息（包含客户和学生信息）
     *
     * @param id 关系ID
     * @return ResultWrapper
     */
    @ApiOperation(value = "获得单条客户关系详细信息", notes = "获得单条客户关系详细信息 - ID")
    @PreAuthorize("hasAuthority('customer_customerrelation_select')")
    @Override
    public ResultWrapper<CustomerStudentRelationModel> getWithDetails(String id) {
        try {
            CustomerStudentRelationModel model = IService.getWithDetails(id);
            return ResultWrapper.getSuccessResultWrapper(model);
        } catch (Exception e) {
            log.error("查询客户关系详细信息失败，ID: {}", id, e);
            return ResultWrapper.getCustomResultWrapper(500, "查询失败");
        }
    }

}